<template>
  <div :class="['auth', { 'auth-collapse': isCollapse }]">
    <div class="auth-header">
      <div class="auth-header-title">
        <span>{{ name }}</span>
      </div>
      <div class="auth-header-center">
        <div class="center-icon">
          <span class="icon-zd" @click="isCollapse = !isCollapse"></span>
          <!-- <span class="icon-yy"></span> -->
          <span class="icon-load" @click="handleReload"></span>
        </div>
        <div class="center-btn">
          <div class="center-btn-item">
            <el-dropdown>
              <span class="center-btn-item">
                <span>{{ user.username }}</span>
                <span class="icon-xl"></span>
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item @click="handleExit">退出</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </div>
      </div>
    </div>
    <div class="auth-container">
      <el-scrollbar class="auth-container-menu" height="100%">
        <el-menu :default-active="activeRoute" mode="vertical" router :collapse-transition="false" :collapse="isCollapse">
          <template v-for="item in user.menu" :key="item.path">
            <template v-if="!item.meta!.hidden">
              <el-sub-menu :index="item.path" v-if="item.children && item.children.length">
                <template #title>
                  <div class="sub-menu-title">
                    <span :class="'icon-' + getIconName(item.path)"></span>
                    <span>{{ item.meta!.title }}</span>
                  </div>
                </template>
                <template v-for="subItem in item.children" :key="subItem.path">
                  <el-sub-menu :index="subItem.path" v-if="subItem.children && subItem.children.length">
                    <template #title>
                      <div class="sub-menu-title">
                        <span :class="'icon-' + getIconName(subItem.path)"></span>
                        <span>{{ subItem.meta!.title }}</span>
                      </div>
                    </template>
                    <el-menu-item :index="i.path" v-for="i in subItem.children" :key="i.path">
                      <template #title>{{ i.meta!.title }}</template>
                    </el-menu-item>
                  </el-sub-menu>
                  <template v-else>
                    <el-menu-item :index="subItem.path" v-if="!subItem.meta?.hidden">
                      <template #title>{{ subItem.meta!.title }}</template>
                    </el-menu-item>
                  </template>
                </template>
              </el-sub-menu>
              <el-menu-item :index="item.path" v-else>
                <span :class="'icon-' + getIconName(item.path)"></span>
                <template #title>{{ item.meta!.title }}</template>
              </el-menu-item>
            </template>
          </template>
        </el-menu>
      </el-scrollbar>
      <div class="auth-container-center">
        <a-card class="center-nav">
          <div class="center-nav-wrapper" ref="wrapperElement">
            <div class="wrapper-content" ref="contentElement">
              <div :class="['wrapper-content-item', { 'wrapper-content-active': isActivePath(item) }]" v-for="(item, index) in routes" :key="index" @click="handleToItem(item)">
                <span class="item-label">{{ item.label }}</span>
                <span class="icon-close" @click.stop="handleRemove(index)" v-if="routes.length > 1"></span>
              </div>
            </div>
          </div>
        </a-card>
        <div class="center-main" id="center-main">
          <el-scrollbar height="100%" class="center-main-scrollbar">
            <router-view></router-view>
          </el-scrollbar>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import BScroll from '@better-scroll/core'
import user from '../store/user'
import getEnv from '../utils/env'
import select from '../store/select'

interface NavItem {
  label: string
  path: string
  children: string[]
}

const route = useRoute()
const router = useRouter()
const name = getEnv('name')
const activeRoute = computed(() => route.path)
const routes = ref<NavItem[]>([])

const wrapperElement = ref<HTMLElement | null>(null)
const contentElement = ref<HTMLElement | null>(null)
const isCollapse = ref(false)

const bs = ref<BScroll | null>(null)

function handleToItem(item: NavItem) {
  router.push({ path: item.path })
}

function handleRemove(index: number) {
  if (routes.value.length === 1) return
  const idx = index === routes.value.length - 1 ? routes.value.length - 2 : index + 1
  if (routes.value[index].path === activeRoute.value) router.push({ path: routes.value[idx].path })
  routes.value.splice(index, 1)
}

function getIconName(path: string) {
  return path.replace('/', '')
}

function handleReload() {
  router.go(0)
}

function handleExit() {
  user.clear()
  window.location.href = '/manager/#/login'
}

function isActivePath(item: NavItem) {
  return [item.path, ...item.children].find((i) => i === activeRoute.value)
}

watch(
  () => route.path,
  () => {
    if (route.meta!.parent && !routes.value.length) {
      router.push({ path: route.meta!.parent as string })
      return
    }
    const current = router.getRoutes().find((i) => i.path === route.path && i.meta!.auth && i.meta!.menu && !i.meta!.hidden)
    if (current) {
      if (!routes.value.some((i) => i.path === current.path)) {
        routes.value.push({
          label: current.meta!.title as string,
          path: current.path,
          children: (current.meta!.children as string[]) || []
        })
      }
    }
  },
  { immediate: true }
)

watch(
  () => [activeRoute.value],
  () => {
    nextTick(() => {
      bs.value!.refresh()
      const { x, scrollBy } = bs.value!

      const index = routes.value.findIndex((i) => i.path === activeRoute.value)
      if (index === -1) return
      const activeElement = contentElement.value!.children[index] as HTMLElement
      const innerLeft = activeElement.offsetLeft < Math.abs(x)
      const innerRight = activeElement.offsetLeft - Math.abs(x) + activeElement.offsetWidth > wrapperElement.value!.clientWidth

      if (innerLeft) {
        scrollBy(-activeElement.offsetLeft - x, 0, 0)
      } else if (innerRight) {
        const right = -(activeElement.offsetLeft + activeElement.offsetWidth - wrapperElement.value!.clientWidth)
        scrollBy(right - x, 0, 0)
      }
    })
  }
)

watch(
  () => routes.value.length,
  () => {
    nextTick(() => {
      bs.value!.refresh()
    })
  }
)

onMounted(() => {
  bs.value = new BScroll(wrapperElement.value!, {
    scrollX: true,
    scrollY: false
  })

  select.loadData()
})
</script>

<style lang="scss">
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}

// .slide-fade-leave-active {
//   transition: all 0.3s ease-out;
// }

.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}

.auth {
  width: 100%;
  height: 100%;
  background-color: $background;
}

.auth-header {
  width: 100%;
  height: $header-height;
  box-sizing: border-box;
  display: flex;
  &-title {
    width: $menu-width;
    height: 100%;
    line-height: $header-height;
    font-weight: bold;
    font-size: $font-size-title;
    text-align: center;
    color: $theme;
    @include text-overflow;
  }
  &-center {
    padding: 0 $padding-large;
    box-sizing: border-box;
    width: calc(100% - #{$menu-width});
    height: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .center-icon {
      font-size: $font-size;
      font-weight: bold;
      display: flex;
      gap: 0 15px;
      span {
        cursor: pointer;
        transition: all 0.5s;
      }
      span:hover,
      .icon-active {
        color: $theme;
      }
    }
    .center-btn {
      display: flex;
      gap: 0 20px;
      &-item {
        display: flex;
        align-items: center;
        gap: 0 5px;
        cursor: pointer;
        span {
          font-weight: bold;
          font-size: $font-size-small;
          color: $color;
          transition: all 0.5s;
        }
      }
      &-item:hover {
        span {
          color: $theme;
        }
      }
    }
  }
}
.auth-container {
  display: flex;
  height: calc(100% - #{$header-height});
  overflow: hidden;
  &-menu {
    width: $menu-width;
    height: 100%;
    user-select: none;
    transition: all 0.3s;
    background-color: #fff;
    border-top-right-radius: $border-radius;
  }
  &-center {
    width: calc(100% - #{$menu-width});
    height: 100%;
    padding: 0 $padding-large;
    box-sizing: border-box;
    transition: all 0.3s;
    .center-nav {
      width: 100%;
      height: $nav-height;
      .a-card-container {
        height: $nav-height;
        padding-top: 0px;
        padding-bottom: 0px;
        display: flex;
        align-items: center;
      }
      &-wrapper {
        width: 100%;
        overflow: hidden;
        .wrapper-content {
          position: relative;
          display: inline-flex;
          gap: 0 10px;
          &-item {
            display: inline-flex;
            align-items: center;
            padding: calc(#{$padding-small} + 2px) $padding;
            font-size: $font-size-mini;
            border-radius: $border-radius;
            cursor: pointer;
            user-select: none;
            gap: 0 5px;
            color: $color;
            background-color: rgba($color: #000000, $alpha: 0.1);
            transition: all 0.3s;
            .item-label {
              display: block;
              max-width: 70px;
              @include text-overflow;
            }
            .icon-close {
              padding: 2px;
              box-sizing: border-box;
              border-radius: $border-radius;
            }
            .icon-close:hover {
              color: $color;
              background-color: #fff;
            }
          }
          &-active,
          &-item:hover {
            background-color: $theme;
            color: #fff;
          }
        }
      }
    }
    .center-main {
      width: 100%;
      height: calc(100% - #{$nav-height} - (#{$margin-large} * 2));
      position: relative;
      &-scrollbar {
        > .is-horizontal {
          display: none !important;
        }
      }
    }
  }
}
.auth-collapse {
  // .auth-header-title {
  //   display: none;
  // }
  // .auth-header-center {
  //   width: 100%;
  // }
  .auth-container-menu {
    width: $menu-width-collapse;
  }
  .auth-container-center {
    width: calc(100% - #{$menu-width-collapse});
  }
  .icon-zd {
    transform: rotate(180deg);
  }
}
</style>
